package com.yl.controller;

import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yl.entity.PermissionEntity;
import com.yl.entity.UserEntity;
import com.yl.utils.MenuTree;
import com.yl.vo.RouterVo;
import com.yl.vo.UserInfoVo;
import com.yl.service.UserService;
import com.yl.utils.JwtUtils;
import com.yl.utils.R;
import com.yl.utils.RedisUtil;
import com.yl.vo.TokenVo;
import com.yl.vo.UserLoginVo;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.web.bind.annotation.*;


/**
 * 用户表
 *
 * @author zlj
 * @email 328727561@qq.com
 * @date 2024-04-17 11:28:08
 */
@RestController
@RequestMapping("/authority/user")
public class UserController {
    @Resource
    private UserService userService;
    @Resource
    private JwtUtils jwtUtils;
    @Resource
    private RedisUtil redisUtil;

    /**
     * 刷新token
     */
    @PostMapping("/refreshToken")
    public R refreshToken(HttpServletRequest request){
        //从header中获取前端提交的token
        String token = request.getHeader("Authorization");
        //如果header中没有参数、则从参数中获取
        if (StrUtil.isEmpty(token)){
            token = request.getParameter("Authorization");
        }
        //获取spring security上下文用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //获取身份信息
        UserDetails userDetails = (UserDetails)authentication.getPrincipal();
        //重新获取token
        String reToken = "";
        //验证原来的token是否合法
        if(jwtUtils.checkToken(token)){
            UserEntity userEntity = new UserEntity();
            if(!StrUtil.isEmpty(userDetails.getUsername())){
                //根据用户查询id
                LambdaQueryWrapper<UserEntity> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(UserEntity::getUsername,userDetails.getUsername());
                userEntity = userService.getOne(wrapper);
                //生成新的token
                reToken = jwtUtils.getJwtToken(userEntity.getId().toString(), userDetails.getUsername());
            }
            //获取到token的到期时间
            long expire = redisUtil.getExpire("token_" + token);
            //清除原来的token信息
            redisUtil.del("token_"+token);
            String newTokenKey = "token_"+reToken;
            //将新的token保存到缓存中去
            redisUtil.set(newTokenKey, reToken,1800);
            TokenVo tokenVo = new TokenVo(expire,reToken);
            return R.ok("token刷新成功!").put("data", tokenVo);
        }
        return R.error();
    }
    /**
     * 获取用户信息
     */
    @GetMapping("/getInfo")
    public R getInfo(){
        //从spring Security上下文获取到用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //判断authentication对象是否为空
        if(authentication == null){
            return R.error("用户信息查询失败!");
        }
        //获取用户信息
        UserEntity user = (UserEntity) authentication.getPrincipal();
        //用户权限集合
        List<PermissionEntity> permissionList = user.getPermissionList();
        //获取角色权限编码字段
        Object[] objects = permissionList.stream().filter(Objects::nonNull).map(PermissionEntity::getCode).toArray();
        UserInfoVo userInfoVo = new UserInfoVo(user.getId(), user.getNickName(), user.getAvatar(), objects);
        return R.ok("查询用户成功").put("data", userInfoVo);
    }
    /**
     * 退出登录
     */
    @PostMapping("/logout")
    public R logout(HttpServletRequest request, HttpServletResponse response){
        //获取到token
        String authorization = request.getHeader("Authorization");
        //如果头部中没有携带token
        if(ObjectUtil.isEmpty(authorization)){
            //参数中获取token
            authorization = request.getParameter("authorization");
        }
        //从spring security 上下文对象中获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //判断用户信息是否为空,如果不为空、则清空用户信息
        if(authentication != null){
            //清除用户的信息
            new SecurityContextLogoutHandler().logout(request, response, authentication);
            //清除Redis缓存中的token
            redisUtil.del("token_"+authorization);
            return R.ok("正在退出系统!");
        }
        return R.error("退出系统失败!");
    }

    /**
     * 获取菜单列表数据
     */
    @GetMapping("/getMenuList")
    public R getMenuList(){
        //从spring Security上下文获取到用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //判断authentication对象是否为空
        if(authentication == null){
            return R.error("用户信息查询失败!");
        }
        //获取用户信息
        UserEntity user = (UserEntity) authentication.getPrincipal();
        //用户权限集合
        List<PermissionEntity> permissionList = user.getPermissionList();
        //筛选当前用户权限拥有的菜单数据
        List<PermissionEntity> collect = permissionList.stream()
                // 0 目录 1菜单
                //只筛选目录与菜单数据，按钮不需要加到路由中
                .filter(e -> e != null && e.getType() != 2).collect(Collectors.toList());
        //生成路由数据
        List<RouterVo> routerVos = MenuTree.makeRouter(collect, 0L);
        return R.ok("菜单数据获取成功").put("data", routerVos);
    }
    /**
     * 列表
     */
    @RequestMapping("/list")
    public R list(@RequestParam Map<String, Object> params){

        return R.ok().put("page", null);
    }


    /**
     * 获取短信验证码
     */
    @PostMapping("/getSMSCode")
    public R getSMSCode(@RequestBody UserEntity user){
        return userService.getSMSCode(user.getPhone());
    }

    /**
     * 注册账号
     */
    @PostMapping("/register")
    public R register(@RequestBody UserEntity user){
        return userService.register(user);

    }
    /**
     * APP登录接口
     */
    @PostMapping("/getAppLogin")
    public R getAppLogin(@RequestBody UserEntity user){
        R r = userService.getAppLogin(user);
        return r;
    }

    /**
     * 密码(MD5)加密
     */
    @PostMapping("/passwordEncryption")
    public R PasswordEncryption(@RequestBody UserEntity user){
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encode = bCryptPasswordEncoder.encode(user.getPassword());
        return R.ok("加密后的密文").put("data", encode);
    }

    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") Long id){
        UserLoginVo userLoginVo = new UserLoginVo();
		UserEntity user = userService.getById(id);
        BeanUtil.copyProperties(user, userLoginVo);
        return R.ok("查询用户成功").put("data", userLoginVo);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    public R save(@RequestBody UserEntity user){
		userService.save(user);
        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    public R update(@RequestBody UserEntity user){
		userService.updateById(user);
        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    public R delete(@RequestBody Long[] ids){
		userService.removeByIds(Arrays.asList(ids));
        return R.ok();
    }
}
